// m

// 给定一个字符串s，找出其中最长的回文子序列，并返回该序列的长度

// 解题思路：动态规划
// 1. 定义状态dp[i][j]表示为：字符串s在[i, j]范围内的最长回文子序列长度
// 2. 状态转移公式为：
//      1. 如果s[i] === s[j],则dp[i][j]为[i+1][j-1]范围内最长回文子序列长度+2，即dp[i][j] = dp[i+1][j-1] + 2
//      2. 如果s[i] !== s[j],则dp[i][j]取决于以下两种情况，取其中最大的一种
//          1. s[i]所能组成的最长回文子序列长度，即dp[i][j] = dp[i][j-1]
//          2. s[j]所能组成的最长回文子序列长度，即dp[i][j] = dp[i+1][j]
// 由于 dp[i][j] 依赖于 dp[i + 1][j - 1]、dp[i + 1][j]、dp[i][j - 1]，所以我们应该按照从下到上、从左到右的顺序进行遍历。
// 最后输出 [0, size - 1] 范围内最长回文子序列长度，即 dp[0][size - 1] 为最终答案。

function longestPalindromeSubseq(s) {
    let size = s.length
    let dp = new Array(size).fill(0).map(() => new Array(size).fill(0))
    for (let i = 0; i < size; i++) {
        dp[i][i] = 1
    }
    for (let i = size - 1; i >= 0; i--) {
        for (let j = i + 1; j < size; j++) {
            if (s[i] === s[j]) {
                dp[i][j] = dp[i + 1][j - 1] + 2
            } else {
                dp[i][j] = Math.max(dp[i + 1][j], dp[i][j - 1])
            }
        }
    }
    return dp[0][size - 1]
}

let s = "bbbab"
console.log(longestPalindromeSubseq(s))